package com.rzt.cft.service.uc.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.rzt.cft.constant.StatusConstant;
import com.rzt.cft.constant.TypeConstant;
import com.rzt.cft.entity.uc.*;
import com.rzt.cft.mapper.uc.*;
import com.rzt.cft.param.sys.RegisterUser;
import com.rzt.cft.param.uc.UpgradeParam;
import com.rzt.cft.service.CoreServiceImpl;
import com.rzt.cft.service.uc.IUcUserService;
import com.rzt.cft.utils.CustomUtil;
import com.rzt.cft.utils.Md5Utils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

/**
 * <p>
 * 普通用户表 服务实现类
 * </p>
 *
 * @author zhongzhong
 * @since 2020-01-10
 */
@Service
public class UcUserServiceImpl extends CoreServiceImpl<UcUserMapper, UcUser> implements IUcUserService {

    @Autowired
    private UcAccountMapper ucAccountMapper;

    @Autowired
    private UcDistributionTypeMapper ucDistributionTypeMapper;

    @Autowired
    private UcAssetStatisticsMapper ucAssetStatisticsMapper;

    @Autowired
    private UcUserDistributionLogMapper ucUserDistributionLogMapper;


    @Transactional
    @Override
    public Boolean registerUser(String userName, String phone, String email, String account, String headPortrait, String pwd) {
        account = StringUtils.isNotBlank(account) ? account : phone;
        UcUser ucUser = new UcUser();
        ucUser.setNickName(userName);
        ucUser.setPhone(phone);
        ucUser.setAccount(account);
        ucUser.setAccountStatus(0);
        ucUser.setEmail(email);
        ucUser.setHeadPortrait(headPortrait);
        Integer countNum = baseMapper.countNum();
        ucUser.setCode(CustomUtil.getCode(countNum));
        ucUser.setType(TypeConstant.UserType.USER_MEMBER);
        Integer userCount = baseMapper.insert(ucUser);

        if (StringUtils.isBlank(pwd)) {
            pwd = phone.substring(6);
        }
        UcAccount ucAccount = new UcAccount();
        ucAccount.setAccount(account);
        ucAccount.setStatus(0);
        String salt = UUID.randomUUID().toString();
        ucAccount.setSalt(salt);
        ucAccount.setUserId(ucUser.getId());
        ucAccount.setPassword(Md5Utils.shiroMD5(salt, pwd));
        Integer count = ucAccountMapper.insert(ucAccount);

        return retBool(count) && retBool(userCount);
    }

    @Override
    @Transactional
    public Boolean appRegisterUser(RegisterUser registerUser) {
        List<UcDistributionType> ucDistributionTypeList = ucDistributionTypeMapper.selectList(null);
        UcDistributionType ucDistributionType = CustomUtil.first(ucDistributionTypeList, x -> x.getIsDefault());
        UcUser ucUser = new UcUser();
        ucUser.setAccount(registerUser.getAccount());
        ucUser.setPhone(registerUser.getPhone());
        ucUser.setAccountStatus(StatusConstant.UcUserStatus.ENABLE);
        ucUser.setType(TypeConstant.UserType.USER_MEMBER);
        ucUser.setEmail(registerUser.getEmail());
        if (Objects.nonNull(ucDistributionType)) {
            ucUser.setDistributionId(ucDistributionType.getId());
            ucUser.setDistributionName(ucDistributionType.getName());
        }

        if (StringUtils.isNotBlank(registerUser.getParentId())) {
            QueryWrapper<UcUser> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("code", registerUser.getParentId());
            UcUser parent = baseMapper.selectOne(queryWrapper);
            if (Objects.nonNull(parent)) {
                ucUser.setParentId(parent.getId());
                ucUser.setParentCode(ucUser.getCode());
                UpgradeParam upgradeParam = new UpgradeParam();
                upgradeParam.setId(parent.getId());
                upgradeParam.setNum(1);
                numUpgrade(upgradeParam);
            }
        }
        Integer count = baseMapper.countNum();
        String code = CustomUtil.getCode(count);
        ucUser.setCode(code);
        Integer userCount = baseMapper.insert(ucUser);

        UcAccount ucAccount = new UcAccount();
        ucAccount.setAccount(registerUser.getAccount());
        ucAccount.setStatus(StatusConstant.UcUserStatus.ENABLE);
        String salt = UUID.randomUUID().toString();
        ucAccount.setSalt(salt);
        ucAccount.setUserId(ucUser.getId());
        ucAccount.setPassword(Md5Utils.shiroMD5(salt, registerUser.getPassword()));
        Integer accountCount = ucAccountMapper.insert(ucAccount);
        return retBool(userCount) && retBool(accountCount);
    }

    @Override
    public void numUpgrade(UpgradeParam param) {
        UcUser ucUser = baseMapper.selectById(param.getId());
        QueryWrapper<UcUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id", ucUser.getId());
        int count = baseMapper.selectCount(queryWrapper);
        List<UcDistributionType> ucDistributionTypes = ucDistributionTypeMapper.selectList(null);
        UcDistributionType old = CustomUtil.first(ucDistributionTypes, x -> x.getId().equals(ucUser.getDistributionId()));
        ucDistributionTypes = CustomUtil.orderBy(ucDistributionTypes, UcDistributionType::getHowNum);
        int size = ucDistributionTypes.size();
        UcDistributionType ucDistributionType = null;
        for (int i = 0; i < size; i++) {
            if (count < ucDistributionTypes.get(i).getHowNum()) {
                ucDistributionType = i == 0 ? ucDistributionTypes.get(i) : ucDistributionTypes.get(i - 1);
                break;
            }
        }
        if (Objects.isNull(ucDistributionType)) {
            ucDistributionType = ucDistributionTypes.get(size - 1);
        }
        if (old.getId() != ucDistributionType.getId()
                && Integer.parseInt(old.getLevel()) < Integer.parseInt(ucDistributionType.getLevel())) {
            ucUser.setDistributionId(ucDistributionType.getId());
            ucUser.setDistributionName(ucDistributionType.getName());
            baseMapper.updateById(ucUser);

            UcUserDistributionLog ucUserDistributionLog = new UcUserDistributionLog();
            ucUserDistributionLog.setUserId(ucUser.getId());
            ucUserDistributionLog.setNum(count);
            ucUserDistributionLog.setDistributionId(ucDistributionType.getId());
            ucUserDistributionLogMapper.insert(ucUserDistributionLog);
        }
    }

    @Override
    public void moneyUpgrade(UpgradeParam param) {
        UcUser ucUser = baseMapper.selectById(param.getId());
        QueryWrapper<UcAssetStatistics> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", ucUser.getId());
        queryWrapper.eq("current", true);
        UcAssetStatistics ucAssetStatistics = ucAssetStatisticsMapper.selectOne(queryWrapper);
        BigDecimal amount = ucAssetStatistics.getAccumulationInjection();
        List<UcDistributionType> ucDistributionTypes = ucDistributionTypeMapper.selectList(null);
        UcDistributionType old = CustomUtil.first(ucDistributionTypes, x -> x.getId().equals(ucUser.getDistributionId()));
        if (Objects.isNull(old)) {
            return;
        }
        ucDistributionTypes = CustomUtil.orderBy(ucDistributionTypes, UcDistributionType::getHowMoney);
        int size = ucDistributionTypes.size();
        UcDistributionType ucDistributionType = null;
        for (int i = 0; i < size; i++) {
            UcDistributionType distributionType = ucDistributionTypes.get(i);
            if (amount.compareTo(distributionType.getHowMoney()) < 0) {
                ucDistributionType = i == 0 ? distributionType : ucDistributionTypes.get(i - 1);
                break;
            }
        }
        if (Objects.isNull(ucDistributionType)) {
            ucDistributionType = ucDistributionTypes.get(size - 1);
        }
        if (old.getId() != ucDistributionType.getId()
                && Integer.parseInt(old.getLevel()) < Integer.parseInt(ucDistributionType.getLevel())) {
            ucUser.setDistributionId(ucDistributionType.getId());
            ucUser.setDistributionName(ucDistributionType.getName());
            baseMapper.updateById(ucUser);

            UcUserDistributionLog ucUserDistributionLog = new UcUserDistributionLog();
            ucUserDistributionLog.setUserId(ucUser.getId());
            ucUserDistributionLog.setMoney(amount);
            ucUserDistributionLog.setDistributionId(ucDistributionType.getId());
            ucUserDistributionLogMapper.insert(ucUserDistributionLog);
        }
    }

}
